#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>

#define TEMP_FILE_PATH "/sys/bus/w1/devices/28-021792455bae/w1_slave" // 本机的DS18B20设备路径

// GPIO引脚定义
#define BUZZER_PIN 0
#define LED_RED_PIN 1
#define LED_GREEN_PIN 2
#define LED_BLUE_PIN 3

// 初始化GPIO
void gpio_init() {
    system("gpio mode 0 out"); // 设置蜂鸣器引脚为输出模式
    system("gpio mode 1 out"); // 设置红色LED引脚为输出模式
    system("gpio mode 2 out"); // 设置绿色LED引脚为输出模式
    system("gpio mode 3 out"); // 设置蓝色LED引脚为输出模式
}

// 设置GPIO电平
void gpio_set(int pin, int value) {
    char command[32];
    sprintf(command, "gpio write %d %d", pin, value);
    system(command);
}

// 读取DS18B20温度
float read_temperature() {
    int fd;
    char buf[128];
    char tempBuf[6];
    float temp = -128.0;

    fd = open(TEMP_FILE_PATH, O_RDONLY);
    if (fd < 0) {
        perror("open device file error");
        return temp;
    }

    if (read(fd, buf, sizeof(buf)) < 0) {
        perror("read() error");
        close(fd);
        return temp;
    }

    close(fd);
    char *t_pos = strstr(buf, "t=");
    if (t_pos) {
        t_pos += 2; // 跳过 "t=" 后的两个字符
        temp = atof(t_pos) / 1000.0; // 转换为浮点数
    }

    return temp;
}

// 定义全局变量存储温度区间
float comfort_low = 20.0;
float comfort_high = 25.0;
float severe_low = 15.0;
float severe_high = 30.0;

// 定义全局变量控制监控状态
volatile sig_atomic_t monitoring = 0;

// 监控线程函数
void *monitoring_thread(void *data) {
    float temp;

    gpio_init();

    while (monitoring) {
        temp = read_temperature();
        if (temp == -128.0) {
            printf("读取温度失败！\n");
            continue;
        }

        printf("当前房间温度：%.2f°C\n", temp);

        if (temp >= comfort_low && temp <= comfort_high) {
            printf("温度适宜\n");
            gpio_set(LED_GREEN_PIN, 1); // 绿灯亮
            gpio_set(LED_RED_PIN, 0);  // 红灯灭
            gpio_set(LED_BLUE_PIN, 0); // 蓝灯灭
            gpio_set(BUZZER_PIN, 0);   // 蜂鸣器关闭
        } else if (temp > comfort_high && temp <= severe_high) {
            printf("方法0（降温）\n");
            gpio_set(LED_BLUE_PIN, 1); // 蓝灯亮
            gpio_set(LED_GREEN_PIN, 0); // 绿灯灭
            gpio_set(LED_RED_PIN, 0);  // 红灯灭
            gpio_set(BUZZER_PIN, 0);   // 蜂鸣器关闭
        } else if (temp < comfort_low && temp >= severe_low) {
            printf("方法1（升温）\n");
            gpio_set(LED_BLUE_PIN, 1); // 蓝灯亮
            gpio_set(LED_GREEN_PIN, 0); // 绿灯灭
            gpio_set(LED_RED_PIN, 0);  // 红灯灭
            gpio_set(BUZZER_PIN, 0);   // 蜂鸣器关闭
        } else {
            printf("注意房间温度！\n");
            gpio_set(LED_RED_PIN, 1);  // 红灯亮
            gpio_set(LED_GREEN_PIN, 0); // 绿灯灭
            gpio_set(LED_BLUE_PIN, 0); // 蓝灯灭
            gpio_set(BUZZER_PIN, 1);   // 蜂鸣器开启
        }

        sleep(1); // 每1秒读取一次温度
    }

    printf("监控已停止。\n");
    return NULL;
}

// 更新温度区间
void update_temperature_range(GtkWidget *widget, gpointer data) {
    GtkWidget *entry1 = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "entry1"));
    GtkWidget *entry2 = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "entry2"));
    GtkWidget *entry3 = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "entry3"));
    GtkWidget *entry4 = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "entry4"));

    comfort_low = atof(gtk_entry_get_text(GTK_ENTRY(entry1)));
    comfort_high = atof(gtk_entry_get_text(GTK_ENTRY(entry2)));
    severe_low = atof(gtk_entry_get_text(GTK_ENTRY(entry3)));
    severe_high = atof(gtk_entry_get_text(GTK_ENTRY(entry4)));

    printf("更新温度区间：\n");
    printf("适宜温度区间：%.2f - %.2f\n", comfort_low, comfort_high);
    printf("严重不适温度区间：%.2f - %.2f\n", severe_low, severe_high);
}

// 开始监控
void start_monitoring(GtkWidget *widget, gpointer data) {
    if (!monitoring) {
        monitoring = 1;
        pthread_t thread;
        pthread_create(&thread, NULL, monitoring_thread, NULL);
        pthread_detach(thread); // 不需要等待线程结束
    }
}

// 停止监控
void stop_monitoring(GtkWidget *widget, gpointer data) {
    monitoring = 0;
    printf("监控已停止。\n");
}

int main(int argc, char **argv) {
    GtkWidget *window;
    GtkWidget *grid;
    GtkWidget *entry1, *entry2, *entry3, *entry4;
    GtkWidget *button_update, *button_start, *button_stop;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "温度监控");
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    // 创建GTK网格布局
    grid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(window), grid);

    // 添加标题
    GtkWidget *label_title = gtk_label_new("设置温度范围");
    gtk_grid_attach(GTK_GRID(grid), label_title, 0, 0, 2, 1);

    // 创建并设置温度范围输入框
    // entry1: 适宜温度区间低值
    GtkWidget *label1 = gtk_label_new("适宜温度区间低值:");
    gtk_grid_attach(GTK_GRID(grid), label1, 0, 1, 1, 1);
    entry1 = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(entry1), "20.0");
    gtk_grid_attach(GTK_GRID(grid), entry1, 1, 1, 1, 1);

    // entry2: 适宜温度区间高值
    GtkWidget *label2 = gtk_label_new("适宜温度区间高值:");
    gtk_grid_attach(GTK_GRID(grid), label2, 0, 2, 1, 1);
    entry2 = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(entry2), "25.0");
    gtk_grid_attach(GTK_GRID(grid), entry2, 1, 2, 1, 1);

    // entry3: 严重不适温度区间低值
    GtkWidget *label3 = gtk_label_new("严重不适温度区间低值:");
    gtk_grid_attach(GTK_GRID(grid), label3, 0, 3, 1, 1);
    entry3 = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(entry3), "15.0");
    gtk_grid_attach(GTK_GRID(grid), entry3, 1, 3, 1, 1);

    // entry4: 严重不适温度区间高值
    GtkWidget *label4 = gtk_label_new("严重不适温度区间高值:");
    gtk_grid_attach(GTK_GRID(grid), label4, 0, 4, 1, 1);
    entry4 = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(entry4), "30.0");
    gtk_grid_attach(GTK_GRID(grid), entry4, 1, 4, 1, 1);

    // 添加按钮
    button_update = gtk_button_new_with_label("更新温度区间");
    g_signal_connect(button_update, "clicked", G_CALLBACK(update_temperature_range), NULL);
    gtk_grid_attach(GTK_GRID(grid), button_update, 0, 5, 2, 1);

    button_start = gtk_button_new_with_label("开始监控");
    g_signal_connect(button_start, "clicked", G_CALLBACK(start_monitoring), NULL);
    gtk_grid_attach(GTK_GRID(grid), button_start, 0, 6, 1, 1);

    button_stop = gtk_button_new_with_label("停止监控");
    g_signal_connect(button_stop, "clicked", G_CALLBACK(stop_monitoring), NULL);
    gtk_grid_attach(GTK_GRID(grid), button_stop, 1, 6, 1, 1);

    g_object_set_data(G_OBJECT(button_update), "entry1", entry1);
    g_object_set_data(G_OBJECT(button_update), "entry2", entry2);
    g_object_set_data(G_OBJECT(button_update), "entry3", entry3);
    g_object_set_data(G_OBJECT(button_update), "entry4", entry4);

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}
